package com.app.xinfadi.widget.gson;

import android.text.TextUtils;

import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.HttpHeaderParser;
import com.google.gson.Gson;
import com.google.gson.JsonParseException;
import com.app.xinfadi.base.AppException;
import com.app.xinfadi.base.MyApplication;
import com.app.xinfadi.base.ScreenManager;
import com.app.xinfadi.util.LogUtil;
import com.app.xinfadi.util.Toast;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;


public class GsonRequest<T> extends Request<T> {
    private Listener<T> mListener;
    private ErrorListener mErrorListener;
    private String TAG = "GsonRequest_Mine";
    private Gson mGson;
    private Class<T> mClass;


    public GsonRequest(int method, String url, Class<T> clazz, Listener<T> listener, ErrorListener errorListener) {
//        super(method, url, errorListener);
        this(new Gson(), method, url, clazz, listener, errorListener);
    }

    public GsonRequest(String url, Class<T> clazz, Listener<T> listener, ErrorListener errorListener) {
        this(Method.GET, url, clazz, listener, errorListener);
    }

    public GsonRequest(Gson gson, int method, String url, Class<T> clazz, Listener<T> listener, ErrorListener errorListener) {
        super(method, url, errorListener);
        mGson = gson;
        mClass = clazz;
        mListener = listener;
        mErrorListener = errorListener;
    }


    @Override
    protected Response<T> parseNetworkResponse(NetworkResponse response) {
//        LogUtil.e(TAG, "response.statusCode:" + response.statusCode);
        try {
            String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
            LogUtil.v(TAG, getUrl() + ":{" + jsonString + "}");
            if (mGson.fromJson(jsonString, mClass).equals("")) {
                return Response.error(new ParseError());
            }
            Success success = mGson.fromJson(jsonString, Success.class);
            if (!success.success && !TextUtils.isEmpty(success.error_code)) {
                //跑出自定义异常
                throwException(success.error_code);
                return Response.error(new ParseError());
            }
            return Response.success(mGson.fromJson(jsonString, mClass), HttpHeaderParser.parseCacheHeaders(response));
        } catch (NullPointerException e) {
            return Response.error(new ParseError(e));
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JsonParseException e) {
            return Response.error(new ParseError(e));
        }
    }

    /**
     * networkResponse.statusCode != 200
     *
     * @param volleyError
     * @return
     */
    @Override
    public VolleyError parseNetworkError(VolleyError volleyError) {

        if (volleyError.networkResponse != null) {
            LogUtil.e(TAG, "response.statusCode:" + volleyError.networkResponse.statusCode);
            throwException(volleyError.networkResponse.statusCode + "");
        }
        return super.parseNetworkError(volleyError);

    }

    /**
     * 抛出自定义错误异常
     *
     * @param errorCode 错误代码 见String.xml
     */
    public void parseErrorListener(int errorCode) {
        if (mErrorListener != null) {
            byte[] by = new byte[]{};
            Map<String, String> map = new HashMap<String, String>();
            NetworkResponse networkResponse = new NetworkResponse(40001, by, map, false);
            VolleyError volleyError = new VolleyError(networkResponse);
            if (volleyError.networkResponse != null) {
//                LogUtil.e(TAG, "response.statusCode:" + volleyError.networkResponse.statusCode);
                throwException(volleyError.networkResponse.statusCode + "");
            }
            mErrorListener.onErrorResponse(volleyError);
        }
    }

    @Override
    protected void deliverResponse(T response) {
        mListener.onResponse(response);
    }

    /**
     * 抛出错误自定义错误异常
     *
     * @param error_code 错误code
     */
    private AppException throwException(String error_code) {
        AppException appException = new AppException();
        try {
            appException.setError_code(error_code);
            throw appException;
        } catch (AppException e) {
            final AppException ex = e;
            ScreenManager.getInstance().currentActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(MyApplication.getInstance().getApplicationContext(), ex.getMessage(), Toast.LENGTH_SHORT).show();
                }
            });
        }
        return appException;
    }

}


